import os
import sys
from functools import reduce
from math import  exp, log

"""
a1:  区间值模糊数 格式为([],[])

self.q: q值

a2:     区间值模糊数 格式为([],[])

编写时间:2022-6-30 
编写人:吴卓成
参考文献:Pythagorean fuzzy linguistic Muirhead mean
"""

os.path.join(os.path.dirname(__file__), '../../')
sys.path.append(os.path.join(os.path.dirname(__file__), '../../'))

from Utilities.AutoGetOperator.selectPackage import get_func

Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')
class AAGeHM(Operator_IVQ_ROFS):
    def add(self, a1, a2, q=0, x=0, *waste1, **waste2):
        """
            funciton    : A-A算子，区间值广义正交模糊集的 和 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 加法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        if x <= 0:
            x = self.x
        # AA 所定义的 add 法则
        u_f = (1 - exp(-(((-log(1 - u_1_f ** q)) ** x + (-log(1 - u_2_f ** q)) ** x) ** (1 / x)))) ** (1 / q)
        u_r = (1 - exp(-(((-log(1 - u_1_r ** q)) ** x + (-log(1 - u_2_r ** q)) ** x) ** (1 / x)))) ** (1 / q)
        v_f = (exp(-(((-log(v_1_f ** q)) ** x + (-log(v_2_f ** q)) ** x) ** (1 / x)))) ** (1 / q)
        v_r = (exp(-(((-log(v_1_r ** q)) ** x + (-log(v_2_r ** q)) ** x) ** (1 / x)))) ** (1 / q)
        return  ([u_f, u_r], [v_f, v_r])

    def multi(self, a1, a2, q=0, y=0, *waste1, **waste2):
        """
            funciton    : A-A算子，区间值广义正交模糊集的 积 运算
            a1          : 一个模糊集, 形式:（[x,y]，[x,y]）
            a2          : 一个模糊集, 形式:（[x,y]，[x,y]）
            return      : 乘法结果, 形式:（[x,y]，[x,y]）
        """
        u_1_f, u_1_r, v_1_f, v_1_r = *a1[0], *a1[1]
        u_2_f, u_2_r, v_2_f, v_2_r = *a2[0], *a2[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        # AA 所定义的 multi 法则
        u_f = (exp(-(((-log(u_1_f ** q)) ** y + (-log(u_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        u_r = (exp(-(((-log(u_1_r ** q)) ** y + (-log(u_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_f = (1 - exp(-(((-log(1 - v_1_f ** q)) ** y + (-log(1 - v_2_f ** q)) ** y) ** (1 / y)))) ** (1 / q)
        v_r = (1 - exp(-(((-log(1 - v_1_r ** q)) ** y + (-log(1 - v_2_r ** q)) ** y) ** (1 / y)))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def kmulti(self, a, k, q=0, y=0, *waste1, **waste2):
        """
            function : A-A算子，区间值广义正交模糊集的 数乘 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 数乘 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        u_f = (1 - exp(-(k * ((-log(1 - u_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        u_r = (1 - exp(-(k * ((-log(1 - u_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_f = (exp(-(k * ((-log(v_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_r = (exp(-(k * ((-log(v_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def pow(self, a, k, q=0, y=0, *waste1, **waste2):
        """
            function : A-A算子，区间值广义正交模糊集的 乘方 运算
            a        : 一个模糊集, 形式:（[x,y]，[x,y]）
            k        : ka 的常数 k
            return   : 乘方 运算法则 的值，形式：（[x,y]，[x,y]）
        """
        u_a_f, u_a_r, v_a_f, v_a_r = *a[0], *a[1]
        if q <= 0:
            q = self.q
        if y <= 0:
            y = self.x
        # AA 算子中定义的乘方运算
        u_f = (exp(-(k * ((-log(u_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        u_r = (exp(-(k * ((-log(u_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_f = (1 - exp(-(k * ((-log(1 - v_a_f ** q)) ** y)) ** (1 / y))) ** (1 / q)
        v_r = (1 - exp(-(k * ((-log(1 - v_a_r ** q)) ** y)) ** (1 / y))) ** (1 / q)
        return ([u_f, u_r], [v_f, v_r])

    def getResult(self, *waste1, **waste2):
        data = self.data_list
        n =  len(data)
       
        a = self.y
        b = self.z
        a_result = self.multi(self.pow(data[0], a) , self.pow(data[0], b))
        for j in range(1, n):
            a_temp = self.multi(self.pow(data[0], a) , self.pow(data[j], b))
            a_result = self.add(a_result, a_temp)


        for i in range(1, n):
            a_i = self.multi(self.pow(data[i], a) , self.pow(data[i], b))
            for j in range(i+1, n):
                a_j = self.multi(self.pow(data[i], a), self.pow(data[j], b))
                a_i = self.add(a_i, a_j)
            a_result = self.add(a_result, a_i)

        a_result = self.kmulti(a_result, (2/(n * (n+1))))
        a_result = self.pow(a_result, 1 / (a+b))

        return a_result        

if __name__ == '__main__':
    data_list=[([0.31, 0.24], [0.73, 0.72]), ([0.97, 0.12], [0.12, 0.05]),
    ([0.8, 0.52], [0.73, 0.15]), ([0.91, 0.49], [0.42, 0.47]),([0.95, 0.06], [0.19, 0.1])]
    weight_list=[0.1, 0.2, 0.3, 0.1, 0.3],
    Pa =AAGeHM(data_list)
    #伟康数据初始设置，对比数据 得到一致结果
    # Pa.set_q(2)
    # Pa.set_x(2)
    # Pa.set_y(0.5)
    # Pa.set_z(0.5)
    # Pa = GA(list1)
    # Pa = WA(list1,weight_list)
    # Pa = WGA(list1,weight_list)
    # Pa = OWA(list1,weight_list)
    print(Pa.getResult())
